<?php
namespace app\service;

use app\model\SystemConfig;
use think\facade\Log;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use OSS\OssClient;
use Qcloud\Cos\Client;

class StorageService
{
    private $config;
    private $type;

    public function __construct()
    {
        $this->loadConfig();
    }

    /**
     * 加载存储配置
     */
    private function loadConfig()
    {
        $this->config = [
            'type' => SystemConfig::getConfig('storage_type', 'local'),
            'access_key' => SystemConfig::getConfig('storage_access_key'),
            'secret_key' => SystemConfig::getConfig('storage_secret_key'),
            'bucket' => SystemConfig::getConfig('storage_bucket'),
            'domain' => SystemConfig::getConfig('storage_domain'),
            'region' => SystemConfig::getConfig('storage_region'),
            'path_prefix' => SystemConfig::getConfig('storage_path_prefix', 'uploads'),
            'url_prefix' => SystemConfig::getConfig('storage_url_prefix')
        ];
        $this->type = $this->config['type'];
    }

    /**
     * 上传文件
     * @param string $filePath 本地文件路径
     * @param string $saveAs 保存的文件名
     * @return array|false
     */
    public function upload($filePath, $saveAs = null)
    {
        if (!file_exists($filePath)) {
            return false;
        }

        $saveAs = $saveAs ?: basename($filePath);
        $saveAs = $this->config['path_prefix'] . '/' . $saveAs;

        try {
            switch ($this->type) {
                case 'qiniu':
                    return $this->uploadToQiniu($filePath, $saveAs);
                case 'aliyun':
                    return $this->uploadToAliyun($filePath, $saveAs);
                case 'tencent':
                    return $this->uploadToTencent($filePath, $saveAs);
                case 'local':
                default:
                    return $this->uploadToLocal($filePath, $saveAs);
            }
        } catch (\Exception $e) {
            Log::error('文件上传失败：' . $e->getMessage());
            return false;
        }
    }

    /**
     * 上传到七牛云
     */
    private function uploadToQiniu($filePath, $saveAs)
    {
        $auth = new Auth($this->config['access_key'], $this->config['secret_key']);
        $token = $auth->uploadToken($this->config['bucket']);
        $uploadMgr = new UploadManager();

        list($ret, $err) = $uploadMgr->putFile($token, $saveAs, $filePath);
        
        if ($err !== null) {
            throw new \Exception($err->message());
        }

        return [
            'path' => $saveAs,
            'url' => $this->config['domain'] . '/' . $saveAs
        ];
    }

    /**
     * 上传到阿里云OSS
     */
    private function uploadToAliyun($filePath, $saveAs)
    {
        $ossClient = new OssClient(
            $this->config['access_key'],
            $this->config['secret_key'],
            $this->config['domain'],
            true
        );

        $result = $ossClient->uploadFile(
            $this->config['bucket'],
            $saveAs,
            $filePath
        );

        return [
            'path' => $saveAs,
            'url' => $result['info']['url']
        ];
    }

    /**
     * 上传到腾讯云COS
     */
    private function uploadToTencent($filePath, $saveAs)
    {
        $cosClient = new Client([
            'region' => $this->config['region'],
            'credentials' => [
                'secretId' => $this->config['access_key'],
                'secretKey' => $this->config['secret_key']
            ]
        ]);

        $result = $cosClient->putObject([
            'Bucket' => $this->config['bucket'],
            'Key' => $saveAs,
            'Body' => fopen($filePath, 'rb')
        ]);

        return [
            'path' => $saveAs,
            'url' => $result['ObjectURL']
        ];
    }

    /**
     * 上传到本地
     */
    private function uploadToLocal($filePath, $saveAs)
    {
        $savePath = public_path() . $saveAs;
        $saveDir = dirname($savePath);
        
        if (!is_dir($saveDir)) {
            mkdir($saveDir, 0755, true);
        }

        if (copy($filePath, $savePath)) {
            return [
                'path' => $saveAs,
                'url' => $this->config['url_prefix'] . '/' . $saveAs
            ];
        }

        return false;
    }

    /**
     * 删除文件
     */
    public function delete($filePath)
    {
        try {
            switch ($this->type) {
                case 'qiniu':
                    // 实现七牛云删除
                    break;
                case 'aliyun':
                    // 实现阿里云删除
                    break;
                case 'tencent':
                    // 实现腾讯云删除
                    break;
                case 'local':
                default:
                    $fullPath = public_path() . $filePath;
                    if (file_exists($fullPath)) {
                        unlink($fullPath);
                    }
                    break;
            }
            return true;
        } catch (\Exception $e) {
            Log::error('文件删除失败：' . $e->getMessage());
            return false;
        }
    }

    /**
     * 获取文件访问URL
     */
    public function getUrl($filePath)
    {
        if (empty($filePath)) {
            return '';
        }

        switch ($this->type) {
            case 'qiniu':
            case 'aliyun':
            case 'tencent':
                return $this->config['domain'] . '/' . $filePath;
            case 'local':
            default:
                return $this->config['url_prefix'] . '/' . $filePath;
        }
    }
} 